#pragma once
#include <drogon/drogon.h>
#include <functional>
#include <google/protobuf/message.h>
#include <google/protobuf/stubs/callback.h>
#include "trantor/utils/NonCopyable.h"
#include "Base_Response.pb.h"

namespace emoney {
    typedef std::function<void(const drogon::HttpResponsePtr&)> Done;

    class Closure : public google::protobuf::Closure, public trantor::NonCopyable {
      public:
        Closure(drogon::HttpResponsePtr respPtr, google::protobuf::Message* pReqMsg, google::protobuf::Message* pRespMsg, Done& done);
        virtual ~Closure();

      public:
        virtual void Run();
        void SetError(int code = 0, const char* pszErrrMsg = "");
        void SetAsync() {
            mIsAsync = true;
        }
        bool isAsync() {
            return mIsAsync;
        }

        void SetCustomReply(const std::string & reply);
      private:
        Done mDone;
        google::protobuf::Message* mReqMsg;
        google::protobuf::Message* mRespMsg;

        std::string                m_customReply;
        Base_Response              m_BaseResp;
        drogon::HttpResponsePtr    mRespPtr;
        bool                       mIsAsync = false;
    };


    class ClosureDone : public trantor::NonCopyable {
      public:
        ClosureDone(Closure* closure);
        ~ClosureDone();

      private:
        Closure* _closure;
    };
}
